package com.example.everying.utils;


import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.profile.DefaultProfile;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import com.aliyuncs.green.model.v20180509.ImageSyncScanRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.Arrays;

import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;

import java.util.Date;

/**
 * @program: everything
 * @description: 图片配置
 * @author: zw
 * @create: 2025-05-16 16:56
 **/
@Slf4j
@Service
@PropertySource("classpath:application.yaml")
public class ImageUpload {

    @Value("${aliyun.oss.endpoint}")
    private String endpoint = "oss-cn-beijing.aliyuncs.com";
    @Value("${aliyun.oss.accessKeyId}")
    private String accessKeyId = "LTAI5t8SaRP7na1rPDp2HRjp";
    @Value("${aliyun.oss.accessKeySecret}")
    private String accessKeySecret = "5pWa2XgR69iPAFTTknSFfVjD4XqQ13";
    @Value("${aliyun.oss.bucketName}")
    private String bucketName = "everything-dev-tuoyang";
    @Value("${aliyun.oss.urlPrefix}")
    private String urlPrefix = "https://everything-dev-tuoyang.oss-cn-beijing.aliyuncs.com";
    @Value("${aliyun.oss.maxSizeMB}")
    private long maxSizeMB = 20; // 单文件最大限制(MB)
    private final long maxSizeBytes;

    @Value("${aliyun.green.access-key-id}")
    private String greenAccessKeyId;

    @Value("${aliyun.green.access-key-secret}")
    private String greenAccessKeySecret;

    @Value("${aliyun.green.read-timeout:6000}")
    private int readTimeout;

    @Value("${aliyun.green.connect-timeout:3000}")
    private int connectTimeout;

    @Autowired
    private AliGreenModerationUtil aliGreenModerationUtil;

    @Autowired
    private AliVideoModerationUtil aliVideoModerationUtil;

    public ImageUpload() {
        this.maxSizeBytes = maxSizeMB * 1024 * 1024;
    }

   public List<String> uploadImages(MultipartFile[] files) throws IOException {
    long startTime = System.currentTimeMillis();
    log.info("开始处理图片上传，文件数量: {}", files != null ? files.length : 0);

    if (files == null || files.length == 0) {
        return new ArrayList<>();
    }

    List<String> urls = new ArrayList<>(files.length);
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

    try {
        for (int i = 0; i < files.length; i++) {
            MultipartFile file = files[i];
            if (file == null || file.isEmpty()) {
                continue;
            }

            long fileStartTime = System.currentTimeMillis();
            log.info("开始处理第{}个文件: {}, 大小: {} bytes", i+1, file.getOriginalFilename(), file.getSize());

            // 校验文件大小
            if (file.getSize() > maxSizeBytes) {
                System.out.println("文件大小：" + file.getSize() + "====" + maxSizeBytes);
                String message = "文件大小超过限制: " + maxSizeMB + "MB";
                throw new CampusException(message, 201);
            }

            // 校验文件类型
            String contentType = file.getContentType();
            if (contentType == null || !isValidImageType(contentType)) {
                String message = "无效的图片类型: " + contentType;
                throw new CampusException(message, 201);
            }

            // 生成唯一文件名
            String fileName = generateUniqueFileName(file.getOriginalFilename());
            String ossPath = "images/" + fileName;

            // 上传到OSS
            long uploadStartTime = System.currentTimeMillis();
            PutObjectRequest request = new PutObjectRequest(bucketName, ossPath, file.getInputStream());
            ossClient.putObject(request);
            long uploadEndTime = System.currentTimeMillis();
            long uploadDuration = uploadEndTime - uploadStartTime;
            log.info("第{}个文件上传OSS完成，耗时: {} ms", i+1, uploadDuration);

            String imageUrl = urlPrefix + "/" + ossPath;

            if(contentType.startsWith("image/") &&
                    (contentType.endsWith("jpeg") ||
                            contentType.endsWith("png") ||
                            contentType.endsWith("gif") ||
                            contentType.endsWith("webp") ||
                            contentType.endsWith("bmp"))){

                // 图片安全审核
                long scanStartTime = System.currentTimeMillis();
                if (!aliGreenModerationUtil.containsProhibitedContent(imageUrl)) {
                    long scanEndTime = System.currentTimeMillis();
                    long scanDuration = scanEndTime - scanStartTime;
                    log.info("第{}个图片审核通过，耗时: {} ms", i+1, scanDuration);
                    // 构建访问URL
                    urls.add(imageUrl);
                } else {
                    long scanEndTime = System.currentTimeMillis();
                    long scanDuration = scanEndTime - scanStartTime;
                    log.info("第{}个图片审核不通过，耗时: {} ms", i+1, scanDuration);
                    // 审核不通过，删除违规图片
                    ossClient.deleteObject(bucketName, ossPath);
                    log.warn("图片包含敏感内容已删除: {}", ossPath);
                    throw new CampusException("图片包含敏感内容", 201);
                }

            } else if (contentType.startsWith("video/") &&
                    (contentType.endsWith("mp4") ||
                            contentType.endsWith("webm") ||
                            contentType.endsWith("ogg") ||
                            contentType.endsWith("quicktime") ||
                            contentType.endsWith("x-msvideo"))){

                // 视频审核
                long scanStartTime = System.currentTimeMillis();
                if (aliVideoModerationUtil.checkVideo(imageUrl)){
                    long scanEndTime = System.currentTimeMillis();
                    long scanDuration = scanEndTime - scanStartTime;
                    log.info("第{}个视频审核通过，耗时: {} ms", i+1, scanDuration);
                    urls.add(imageUrl);
                } else {
                    long scanEndTime = System.currentTimeMillis();
                    long scanDuration = scanEndTime - scanStartTime;
                    log.info("第{}个视频审核不通过，耗时: {} ms", i+1, scanDuration);
                    // 审核不通过，删除违规图片
                    ossClient.deleteObject(bucketName, ossPath);
                    log.warn("视频包含敏感内容已删除: {}", ossPath);
                    throw new CampusException("视频包含敏感内容", 201);
                }
            }

            long fileEndTime = System.currentTimeMillis();
            long fileDuration = fileEndTime - fileStartTime;
            log.info("第{}个文件处理完成，总耗时: {} ms", i+1, fileDuration);
        }
    } finally {
        ossClient.shutdown();
        long endTime = System.currentTimeMillis();
        long totalDuration = endTime - startTime;
        log.info("图片上传处理完成，总耗时: {} ms，成功上传 {} 个文件", totalDuration, urls.size());
    }

    return urls;
}

    private boolean isImageSafe(String imageUrl) {
        // 创建DefaultProfile实例
        DefaultProfile profile = DefaultProfile.getProfile(
                "cn-beijing",  // 地域ID
                greenAccessKeyId,     // AccessKey ID
                greenAccessKeySecret  // AccessKey Secret
        );
        // 添加endpoint
        DefaultProfile.addEndpoint("cn-beijing", "Green", "green.cn-beijing.aliyuncs.com");
        // 创建IAcsClient实例
        IAcsClient client = new DefaultAcsClient(profile);

        try {
            // 创建同步扫描请求
            ImageSyncScanRequest imageSyncScanRequest = new ImageSyncScanRequest();
            imageSyncScanRequest.setAcceptFormat(FormatType.JSON);
            imageSyncScanRequest.setMethod(MethodType.POST);
            imageSyncScanRequest.setEncoding("utf-8");
            imageSyncScanRequest.setProtocol(ProtocolType.HTTP);

            // 构建请求体
            JSONObject httpBody = new JSONObject();
            // 设置要检测的场景，根据需要添加或删除场景
            httpBody.put("scenes", Arrays.asList(
                    "porn",      // 鉴黄
                    "terrorism", // 暴恐涉政
                    "ad",        // 广告
                    "qrcode",    // 二维码
                    "live",      // 不良场景
                    "logo"       // 商标台标
            ));

            // 设置待检测图片
            JSONObject task = new JSONObject();
            task.put("dataId", UUID.randomUUID().toString());
            task.put("url", imageUrl);
            task.put("time", new Date());
            httpBody.put("tasks", Arrays.asList(task));

            // 设置请求内容
            imageSyncScanRequest.setHttpContent(
                    org.apache.commons.codec.binary.StringUtils.getBytesUtf8(httpBody.toJSONString()),
                    "UTF-8",
                    FormatType.JSON
            );
            // 设置超时时间
            imageSyncScanRequest.setConnectTimeout(connectTimeout);
            imageSyncScanRequest.setReadTimeout(readTimeout);

            // 调用服务端进行图片审核
            HttpResponse httpResponse = client.doAction(imageSyncScanRequest);

            // 处理响应结果
            if (httpResponse.isSuccess()) {
                JSONObject scrResponse = JSON.parseObject(new String(httpResponse.getHttpContent(), "UTF-8"));
                JSONArray taskResults = scrResponse.getJSONArray("data");

                if (taskResults != null && !taskResults.isEmpty()) {
                    JSONObject taskResult = taskResults.getJSONObject(0);
                    // 这里不应该把200当作错误，200是正常的响应码
                    if (taskResult.getInteger("code") == 200) {
                        JSONArray sceneResults = taskResult.getJSONArray("results");
                        // 遍历每个场景的检测结果
                        for (int i = 0; i < sceneResults.size(); i++) {
                            JSONObject sceneResult = sceneResults.getJSONObject(i);
                            String suggestion = sceneResult.getString("suggestion");
                            // 只有当建议为block时才记录警告日志
                            if ("block".equals(suggestion)) {
                                log.warn("图片审核不通过，场景: {}, 建议: {}",
                                        sceneResult.getString("scene"),
                                        suggestion);
                                return false;
                            }
                        }
                        // 所有场景都通过审核
                        log.info("图片审核通过");
                        return true;
                    } else {
                        // 非200状态码才是真正的错误
                        log.error("图片审核服务响应异常，状态码: {}", taskResult.getInteger("code"));
                        return false;
                    }
                }
            }
            // 如果请求失败或解析响应失败，为安全起见返回false
            log.error("图片审核请求失败: {}", httpResponse.getStatus());
            return false;
        } catch (Exception e) {
            log.error("图片审核异常", e);
            return false;
        }
    }

    private String generateUniqueFileName(String originalFilename) {
        String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
        return UUID.randomUUID().toString() + extension;
    }

    private boolean isValidImageType(String contentType) {
        return contentType.startsWith("image/") &&
                (contentType.endsWith("jpeg") ||
                        contentType.endsWith("png") ||
                        contentType.endsWith("gif") ||
                        contentType.endsWith("webp") ||
                        contentType.endsWith("bmp"))
                ||
                contentType.startsWith("video/") &&
                        (contentType.endsWith("mp4") ||
                                contentType.endsWith("webm") ||
                                contentType.endsWith("ogg") ||
                                contentType.endsWith("quicktime") ||
                                contentType.endsWith("x-msvideo"));

    }

}
